package me.yxy.mobanddd.finder;

import com.querydsl.core.BooleanBuilder;
import me.yxy.mobanddd.components.BeanTools;
import me.yxy.mobanddd.components.PredicateTool;
import me.yxy.mobanddd.controller.request.query.TransportPageRequest;
import me.yxy.mobanddd.domain.transportorder.QTransportOrder;
import me.yxy.mobanddd.domain.transportorder.TransportOrder;
import me.yxy.mobanddd.domain.transportorder.TransportOrderRepository;
import me.yxy.mobanddd.finder.view.transport.QTransportConsoleView;
import me.yxy.mobanddd.finder.view.transport.TransportConsoleView;
import me.yxy.mobanddd.finder.view.transport.TransportSimpleView;
import me.yxy.mobanddd.finder.view.transport.TransportViewRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.util.List;

/**
 * 运单查询业务类，所以查询方法全部通过此处
 */
@Service
@Transactional(readOnly = true)
public class TransportOrderFinder {

    @Autowired
    TransportOrderRepository repository;

    @Autowired
    TransportViewRepository transportViewRepository;

    @PersistenceContext
    EntityManager entityManager;

    /**
     * 使用原生的sql来按条件查询
     * @param request
     */
    public List<TransportSimpleView> pageByNativeSql(TransportPageRequest request) {

        String sql = "select * FROM t_transport_order WHERE 1=1";

        sql += andEqual(request.getShipmentId(),"shipment_id");
        sql += andEqual(request.getType(),"type");
        sql += andEqual(request.getCode(),"code");

        Query nativeQuery = entityManager.createNativeQuery(sql, TransportOrder.class);


        List<TransportOrder> result = nativeQuery.getResultList();

        //TODO 再考虑一下分页

        return BeanTools.copyList(result, TransportSimpleView.class);
    }


    /**
     * 单表分页查询
     * 对于单表，允许适当直接暴露DTO出去
     * 虽说并没有完全按照View的规范来，但是在实际操作中，也建议适当允许这样操作，因为对于整体架构来说，算不上非常大的影响，也减少了不必要的View创建
     *
     * @param request
     * @param pageable
     * @return
     */
    public Page<TransportOrder> pageSimple(TransportPageRequest request, Pageable pageable){

        QTransportOrder query = QTransportOrder.transportOrder;

        BooleanBuilder builder = new BooleanBuilder();
        PredicateTool.notNullAnd(builder,request.getCode(),query.code);
        PredicateTool.notNullAnd(builder,request.getType(),query.type);
        PredicateTool.notNullAnd(builder,request.getShipmentId(),query.id);

        Page<TransportOrder> page = repository.findAll(builder,pageable);
        return page;
    }


    /**
     * 运单视图
     * @param pageable
     * @return
     */
    public Page<TransportConsoleView> pageTransportView(TransportPageRequest request, Pageable pageable){


        QTransportConsoleView query = QTransportConsoleView.transportConsoleView;

        BooleanBuilder builder = new BooleanBuilder();
        PredicateTool.notNullAnd(builder,request.getCode(),query.code);
        PredicateTool.notNullAnd(builder,request.getType(),query.type);

        //外键查询
        PredicateTool.notNullAnd(builder,request.getWarehouseId(),query.warehouseId);
        PredicateTool.notNullAnd(builder,request.getShipmentId(),query.shipmentId);

        //区间查询
        PredicateTool.notNullBetween(builder,request.getCreatedTimeStart(),request.getCreatedTimeEnd(),query.createdTime);

        return transportViewRepository.findAll(builder,pageable);
    }



    //TODO 重构一下，做成一个工具
    private String andEqual(Object value, String column) {
        return !ObjectUtils.isEmpty(value) ? " AND "+column +"="+value : "";
    }
}
